package com.timedomain.him.remake.utils;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.timedomain.him.remake.models.ChatMessage;
import com.timedomain.him.remake.models.CompanionPhoneCall;
import com.timedomain.him.remake.models.MorningCall;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

public class BackupRestoreUtils {
    public static String dumpData(Context ctx) throws IllegalAccessException {
        Gson gson = new GsonBuilder().setPrettyPrinting().create();

        BackupDataHolder dataHolder = new BackupDataHolder();
        dataHolder.appSettings = (AppSettings.SettingHolderObject) SettingUtils.loadAllSetting(ctx, AppSettings.SettingHolderObject.class,false);
        dataHolder.chatMessages = DB.ChatMessage.dumpData();
        dataHolder.companionPhoneCalls = DB.CompanionPhoneCall.dumpData();
        dataHolder.morningCalls = DB.MorningCall.dumpData();
        dataHolder.morningCallFreqPairs = MorningCallManager.MorningCallFreqCounter.dumpData(ctx);

        try {
            var appPackage = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),0);
            dataHolder.appVersionCode = appPackage.versionCode;
            dataHolder.appVersionName = appPackage.versionName;
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }

        dataHolder.backupTime = System.currentTimeMillis();
        String deviceName = Settings.Secure.getString(ctx.getContentResolver(), "bluetooth_name");
        HLog.d("Device name is",deviceName);
        if(TextUtils.isEmpty(deviceName)){
            deviceName = Build.MODEL;
        }

        dataHolder.backupUserName = deviceName;
        dataHolder.officialDataPackVersion = DataPackManager.getOfficialReleaseDataPack().version;
        dataHolder.installedDataPack = DataPackManager.getInstalledDataPacks();

        return gson.toJson(dataHolder);
    }

    private static void checkBackupFileCompatible(Context ctx,BackupDataHolder dataHolder) throws BackupIncompatibleException{
        try {
            var appPackage = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(),0);
            if(appPackage.versionCode < dataHolder.appVersionCode){
                throw new BackupIncompatibleException("存档文件创建的版本高于当前版本。建议更新APP");
            }
            if(appPackage.versionCode == dataHolder.appVersionCode){
                if(DataPackManager.getOfficialReleaseDataPack().version < dataHolder.officialDataPackVersion){
                    throw new BackupIncompatibleException("存档文件创建的数据包版本高于当前版本。建议安装更新数据包");
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }
        HashSet<String> installedPackages = new HashSet<>();
        for (var item:
             DataPackManager.getInstalledDataPacks() ) {
            installedPackages.add(item.id);
        }
        for (var item:
             dataHolder.installedDataPack) {
            if(!installedPackages.contains(item.id)){
                throw new BackupIncompatibleException("未安装数据包："+item.name+" ("+item.id+")，建议安装对应数据包后再读取数据");
            }
        }


    }

    public static BackupDataHolder getData(String fileData){
        Gson gson = new Gson();
        BackupDataHolder data = gson.fromJson(fileData,BackupDataHolder.class);
        return data;
    }

    public static void restoreData(Context ctx,BackupDataHolder data ) throws IllegalAccessException, BackupIncompatibleException {

        // 检查是否可以读取这个备份
        checkBackupFileCompatible(ctx,data);
        SettingUtils.saveAllSetting(ctx, AppSettings.SettingHolderObject.class,false,data.appSettings);
        DB.ChatMessage.restoreData(data.chatMessages);
        DB.MorningCall.restoreData(data.morningCalls);
        DB.CompanionPhoneCall.restoreData(data.companionPhoneCalls);
        MorningCallManager.MorningCallFreqCounter.restoreData(ctx,data.morningCallFreqPairs);
        AppSettings.loadSettings(ctx);
        AppSettings.hasSeenBatteryOptimizationDialog = false;
        AppSettings.saveSettings(ctx);
    }

    public static class BackupDataHolder{

        public List<MorningCall> morningCalls;

        public List<CompanionPhoneCall> companionPhoneCalls;

        public List<ChatMessage> chatMessages;

        public List<MorningCallManager.MorningCallFreqCounter.MorningCallFreqPair> morningCallFreqPairs;

        public AppSettings.SettingHolderObject appSettings;

        public String backupUserName = "";

        public long backupTime = -1;

        public long appVersionCode=  -1;

        public String appVersionName = "";

        public int officialDataPackVersion = -1;

        public List<DataPackManager.DataPackMetadata> installedDataPack;
    }

    public static class BackupIncompatibleException extends Exception{

        public BackupIncompatibleException(String s) {
            super(s);
        }
    }
}
